package org.byacko.simplemock;

import java.lang.reflect.Method;

/**
 * メソッドフックのシグネチャをあわらすクラス
 * 
 * @author koumiya
 * 
 */
public abstract class MethodHook {

	private String methodName;
	private Class<?>[] argTypes;
	private Object returnValue;
	private Throwable throwable;
	private Object delegate;
	private ResultType resultType;

	protected MethodHook(String methodName, Class<?>[] argTypes) {
		this.methodName = methodName;
		this.argTypes = argTypes;
	}

	public Object process(Method method, Object[] args) throws Throwable {
		switch (this.resultType) {
		case RETUEN:
			return this.returnValue;
		case RAISE:
			throw throwable;
		case DELEGATE:
			return method.invoke(delegate, args);
		default :
			throw new IllegalStateException("ResultTypeが初期化されていません。");
		}
	}

	public boolean isNoArgs() {
		return argTypes.length == 0;
	}

	public String getMethodName() {
		return methodName;
	}

	public Class<?>[] getArgTypes() {
		return argTypes;
	}

	public MethodHook setReturn(Object value) {
		this.returnValue = value;
		this.resultType = ResultType.RETUEN;
		return this;
	}

	public MethodHook setRaise(Throwable throwable) {
		this.throwable = throwable;
		this.resultType = ResultType.RAISE;
		return this;
	}

	public MethodHook setDelegate(Object delegate) {
		this.delegate = delegate;
		this.resultType = ResultType.DELEGATE;
		return this;
	}
}
